﻿Imports System.Text.RegularExpressions

Public Class Startup

#Region " Declarations "

    Private tcpServer As TCPServer
    Private tcpClient As TCPClient
    Private myPlayer As Player

#End Region

#Region " Events "

    ''' <summary>
    ''' Displays IPv4 info on startup
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Startup_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Try
            Dim xEntry As System.Net.IPHostEntry = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName)
            Dim ipAddr As Net.IPAddress() = xEntry.AddressList
            'Pick the IPv4 format
            For Each ip As Net.IPAddress In ipAddr
                If Regex.IsMatch(ip.ToString.Trim(), "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", RegexOptions.IgnoreCase) Then
                    txtIP.Text = ip.ToString.Trim()
                End If
            Next
            lblHostName.Text = System.Net.Dns.GetHostName
        Catch
        End Try
    End Sub

    ''' <summary>
    ''' Launches game table and adds computer players needed to fill out game on click
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>Available only to host</remarks>
    Private Sub btnStartGame_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStartGame.Click
        If tcpServer Is Nothing Then
            MessageBox.Show("Must be game host to begin", "Action Necessary", MessageBoxButtons.OK, MessageBoxIcon.None)
        Else
            Dim clients As List(Of ConnectedClient) = tcpServer.GetClients
            Dim players As New List(Of Player)
            Dim player As Player = Nothing
            For Each client In clients
                player = New Player(client)
                players.Add(player)
            Next

            'Launch game form and close this window
            Dim game As New Game(players)
            game.Start()
        End If
    End Sub

    ''' <summary>
    ''' Sets up TCP server for hosting a game on click.
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub btnCreateGame_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCreateGame.Click
        If tcpServer Is Nothing Then
            tcpServer = New TCPServer()
            tcpServer.StartServer()
            btnCreateGame.Enabled = False
        End If
    End Sub

    ''' <summary>
    ''' Attempts to join a hosted game, will pop up an input box for the host IP.
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub btnJoinGame_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnJoinGame.Click
        Try
            If txtUsername.Text.Length < 1 Then
                ErrorProvider1.SetError(txtUsername, "Must have a username to join")
            ElseIf txtUsername.Text.Contains(";") Or txtUsername.Text.Contains("|") Or txtUsername.Text.Contains(vbCr) Then
                ErrorProvider1.SetError(txtUsername, "Username cannot contains characters ';', '|', or '<carriage return>'")
            Else
                'Ask for IP, port entries
                Dim ip As String = InputBox("Enter the IP Address to connect to:", "Enter Host", "localhost")
                tcpClient = New TCPClient(ip)
                tcpClient.StartClient(Me)
                'Don't allow any more connections so as not to get confused
                btnJoinGame.Enabled = False
                txtUsername.Enabled = False
                If tcpClient IsNot Nothing Then
                    Dim pos As String = tcpClient.GetPosition()
                    myPlayer = New Player(txtUsername.Text, pos)
                    SetPlayerPositionLabelText(myPlayer.Position())
                End If
            End If
        Catch a As Exception
        End Try
    End Sub

    ''' <summary>
    ''' Cleans up client threads and exits.
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Startup_Closing(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.FormClosing
        If tcpClient IsNot Nothing Then
            tcpClient.Close()
        End If
        If tcpServer IsNot Nothing Then
            tcpServer.Close()
        End If
    End Sub

#End Region

#Region " Delegate Form Update "

    ''' <summary>
    ''' Delegate sub for this form instance
    ''' </summary>
    ''' <param name="text"></param>
    ''' <remarks></remarks>
    Public Delegate Sub SetConnectionLabelTextDelegate(ByVal text As String)

    ''' <summary>
    ''' Delegate sub for this form instance
    ''' </summary>
    ''' <param name="text"></param>
    ''' <remarks></remarks>
    Public Delegate Sub SetPlayerCountLabelTextDelegate(ByVal text As String)

    ''' <summary>
    ''' Delegate sub for this form instance
    ''' </summary>
    ''' <param name="text"></param>
    ''' <remarks></remarks>
    Public Delegate Sub SetPlayerPositionLabelTextDelegate(ByVal text As String)

    ''' <summary>
    ''' Delegate sub for this form instance
    ''' </summary>
    ''' <param name="text"></param>
    ''' <remarks></remarks>
    Public Delegate Sub AddPlayerToListViewDelegate(ByVal text As String)

    ''' <summary>
    ''' Delegate sub for this form instance
    ''' </summary>
    ''' <remarks></remarks>
    Public Delegate Sub PromptUserForNewUsernameDelegate()

    ''' <summary>
    ''' Updates the connection status label for joining the server.
    ''' </summary>
    ''' <param name="text">String to display connection status</param>
    ''' <remarks></remarks>
    Public Sub SetConnectionLabelText(ByVal text As String)
        If Me.lblConnection.InvokeRequired Then
            Me.BeginInvoke(New Startup.SetConnectionLabelTextDelegate(AddressOf SetConnectionLabelText), text)
        Else
            Me.lblConnection.Text = text
        End If
    End Sub

    ''' <summary>
    ''' Updates the Players Joined label with the server's count of players joined.
    ''' </summary>
    ''' <param name="text">String to display client count</param>
    ''' <remarks></remarks>
    Public Sub SetPlayerCountLabelText(ByVal text As String)
        If Me.lblPlayersJoined.InvokeRequired Then
            Me.BeginInvoke(New Startup.SetPlayerCountLabelTextDelegate(AddressOf SetPlayerCountLabelText), text)
        Else
            Me.lblPlayersJoined.Text = text
        End If
    End Sub

    ''' <summary>
    ''' Updates the Players Joined label with the server's count of players joined.
    ''' </summary>
    ''' <param name="text">String to display client count</param>
    ''' <remarks></remarks>
    Public Sub SetPlayerPositionLabelText(ByVal text As String)
        If Me.lblPlayersJoined.InvokeRequired Then
            Me.BeginInvoke(New Startup.SetPlayerPositionLabelTextDelegate(AddressOf SetPlayerPositionLabelText), text)
        Else
            Me.lblPositionNumber.Text = text
        End If
    End Sub

    ''' <summary>
    ''' Updates the Players Joined label with the server's count of players joined.
    ''' </summary>
    ''' <param name="text">String to display client count</param>
    ''' <remarks></remarks>
    Public Sub AddPlayerToListView(ByVal text As String)
        If Me.lstTablePlayers.InvokeRequired Then
            Me.BeginInvoke(New Startup.AddPlayerToListViewDelegate(AddressOf AddPlayerToListView), text)
        Else

            Dim players() As String = text.Split(";"c)
            Me.lstTablePlayers.Items.Clear()
            For Each plyr As String In players
                Me.lstTablePlayers.Items.Add(plyr)
            Next
        End If
    End Sub

    ''' <summary>
    ''' The username entered is taken, prompts player to use a new one (reenables Join button)
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub PromptUserForNewUsername()
         'renables the Join button to join again
        If Me.InvokeRequired Then
            Me.BeginInvoke(New Startup.PromptUserForNewUsernameDelegate(AddressOf PromptUserForNewUsername))
        Else
            Try
                MessageBox.Show("There is already a player with that name, please input a new one and retry", "Duplicate Username detected", MessageBoxButtons.OK, MessageBoxIcon.Warning)

                Me.btnJoinGame.Enabled = True
                Me.txtUsername.Enabled = True
                Me.txtUsername.ResetText()
                Me.lblConnection.ResetText()
                Me.lblPlayersJoined.ResetText()
                Me.lblPositionNumber.ResetText()
                Me.lstTablePlayers.Items.Clear()
                'tcpClient.Close()
            Catch
            End Try
        End If
    End Sub

#End Region

End Class
